#include "Vector3.hh"

namespace plato {

Vector3::Vector3(Domain *domain, VarID parent, PlatoVariableSyncType sync_type)
  : StructVariable(domain, parent, sync_type),
    x(domain->New<Float>(sync_type)),
    y(domain->New<Float>(sync_type)),
    z(domain->New<Float>(sync_type)) {
  }

Vector3::~Vector3() {}

auto Vector3::New(Domain *domain, VarID parent, PlatoVariableSyncType sync_type) -> std::shared_ptr<Vector3> {
  return plato::make_shared<Vector3>(domain->mem_block(), domain, parent, sync_type);
}

auto Vector3::serialize(PlatoStream &stream) -> bool {
  stream << id();
  x->serialize(stream);
  y->serialize(stream);
  z->serialize(stream);
  return true;
}

auto Vector3::deserialize(PlatoStream &stream) -> bool {
  stream.skip(sizeof(VarID));
  x->deserialize(stream);
  y->deserialize(stream);
  z->deserialize(stream);
  return true;
}

auto Vector3::copy(Variable *other) -> void {
  auto *ptr = dynamic_cast<Vector3 *>(other);
  if (!ptr) { return; }
  x->copy(ptr->x.get());
  y->copy(ptr->y.get());
  z->copy(ptr->z.get());
}

auto Vector3::object_size() -> std::size_t {
  return sizeof(Vector3);
}

auto Vector3::copy_default() -> void {
  x->copy_default();
  y->copy_default();
  z->copy_default();
}

auto Vector3::complete_prototype() -> void { copy_default(); }

auto Vector3::get_fixed_mem_size() -> std::size_t {
  std::size_t total_size = sizeof(Vector3);
  total_size += sizeof(Float);
  total_size += sizeof(Float);
  total_size += sizeof(Float);
  return total_size;
}

}

